package com.fand.persistent.support;

import java.util.List;
import java.util.Map;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import org.apache.commons.lang.StringUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.util.CollectionUtils;

import com.fand.router.support.RouterKeySupport;
import com.fand.template.utils.TemplateUtils;

/**
 * 路由键名
 * 
 * @author yaoHT
 */
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class RouterKeyDefaultSupport implements RouterKeySupport {
	private static final String CACHE_NAME = "routerNamedParameterJdbcTemplateChche";

	private RouterKeyConfig defaultRouterKeyConfig;

	/**
	 * 路由键名配置
	 */
	private Map<String, RouterKeyConfig> routerKeyConfigs;

	@Override
	@Cacheable(value = RouterKeyDefaultSupport.CACHE_NAME, key = "#key")
	public String getGroupId(final String key) {
		return null;
	}

	private String getKey(final List<RouterKeyConfig> routerKeyConfigs, final String value, final Object model) {
		if (CollectionUtils.isEmpty(routerKeyConfigs)) {
			return null;
		}

		for (final RouterKeyConfig routerKeyConfig : routerKeyConfigs) {
			if (!StringUtils.startsWith(value, routerKeyConfig.getPrefix())) {
				continue;
			}

			final String key = this.getKey(routerKeyConfig.getChilds(), value, model);

			if (StringUtils.isNotBlank(key)) {
				return key;
			}

			String expressionKey = null;

			if (org.apache.commons.lang.StringUtils.isNotBlank(routerKeyConfig.getExpression())) {
				expressionKey = TemplateUtils.processString(routerKeyConfig.getExpression(), model);
			}

			return this.getKey(routerKeyConfig, expressionKey);
		}

		return null;
	}

	private String getKey(final RouterKeyConfig routerKeyConfig, String expressionKey) {
		if (CollectionUtils.isEmpty(routerKeyConfig.getKeys())) {
			return com.fand.utils.StringUtils.defaultIfBlank(routerKeyConfig.getTargetKey(),
					routerKeyConfig.getDefaultKey());
		}

		if (!routerKeyConfig.getKeys().contains(routerKeyConfig.getDefaultKey())) {
			routerKeyConfig.setDefaultKey(routerKeyConfig.getKeys().get(0));
		}

		if (!routerKeyConfig.getKeys().contains(routerKeyConfig.getTargetKey())) {
			routerKeyConfig.setTargetKey(routerKeyConfig.getDefaultKey());
		}

		expressionKey = StringUtils.trim(expressionKey);

		if (routerKeyConfig.getKeys().contains(expressionKey)) {
			return expressionKey;
		}

		return com.fand.utils.StringUtils.defaultIfBlank(routerKeyConfig.getTargetKey(),
				routerKeyConfig.getDefaultKey());
	}

	private String getKey(final RouterKeyConfig routerKeyConfig, final String value, final Object model) {
		if (routerKeyConfig == null) {
			return null;
		}

		final String key = this.getKey(routerKeyConfig.getChilds(), value, model);

		if (StringUtils.isNotBlank(key)) {
			return key;
		}

		String expressionKey = null;

		if (org.apache.commons.lang.StringUtils.isNotBlank(routerKeyConfig.getExpression())) {
			expressionKey = TemplateUtils.processString(routerKeyConfig.getExpression(), model);
		}

		return this.getKey(routerKeyConfig, expressionKey);
	}

	@Override
	@Cacheable(value = RouterKeyDefaultSupport.CACHE_NAME)
	public String getKey(final String groupId, final String value, final Object model) {
		if (StringUtils.isBlank(value)) {
			return this.getKey(this.defaultRouterKeyConfig, null);
		}

		if (StringUtils.isBlank(groupId)) {
			return this.getKey(this.defaultRouterKeyConfig, null);
		}

		if (CollectionUtils.isEmpty(this.routerKeyConfigs)) {
			return this.getKey(this.defaultRouterKeyConfig, null);
		}

		if (this.routerKeyConfigs.containsKey(groupId)) {
			final RouterKeyConfig routerKeyConfig = this.routerKeyConfigs.get(groupId);

			final String key = this.getKey(routerKeyConfig, value, model);

			if (StringUtils.isNotBlank(key)) {
				return key;
			}
		}

		return this.getKey(this.defaultRouterKeyConfig, null);
	}

	@Override
	@CacheEvict(value = RouterKeyDefaultSupport.CACHE_NAME, allEntries = true)
	public void reload() {
	}

	@Override
	@CachePut(value = RouterKeyDefaultSupport.CACHE_NAME, key = "#key")
	public String setGroupId(final String key, final String groupId) {
		return groupId;
	}
}
